package com.trainoo.alert.service;

import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.taobao.api.ApiException;
import org.apache.tomcat.util.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @Auther: zt
 * @Date: 2020/4/10 14:22
 * @Description:
 */
@Service
public class SendDingTalkService implements IService{

    private static final Logger LOG = LoggerFactory.getLogger(SendDingTalkService.class);

    @Value("${dingTalk.signSecret}")
    private String signSecret;
    @Value("${dingTalk.accessToken}")
    private String accessToken;

    @Override
    public void alert(String mailData) {
        LOG.info("开始发送钉钉告警信息");
        Long timestamp = System.currentTimeMillis();
        String sign = getSign(timestamp);
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/robot/send?access_token=" + accessToken + "&timestamp=" + timestamp + "&sign=" + sign);

        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("markdown");
        OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
        markdown.setTitle("服务器告警通知");
        markdown.setText(formatMessage(mailData));
        request.setMarkdown(markdown);
        try {
            client.execute(request);
        } catch (ApiException e) {
            LOG.error("发送钉钉告警信息异常", e);
        }
    }

    private String getSign(Long timestamp){
        try {
            String stringToSign = timestamp + "\n" + signSecret;
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(signSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
            return URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) {
            LOG.error("钉钉生成签名发生异常", e);
            throw new RuntimeException(e);
        }
    }

    private String formatMessage(String mailData){
        JSONObject data = JSONObject.parseObject(mailData);
        String format = "## 服务器告警通知\n" +
                "- 服务器：%s 发现异常\n" +
                "- 异常发生时间：%s\n" +
                "- 触发告警规则：%s\n" +
                "- 简略信息：%s\n";
        return String.format(format, data.get("host"), data.get("@timestamp"), data.get("rule"), data.get("message"));
    }
}
